package com.sugon.modules.device.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import com.sugon.dao.*;
import com.sugon.entity.*;
import com.sugon.modules.base.model.vo.ProcessProgressConst;
import com.sugon.modules.device.consts.DevFaultPreventProgress;
import com.sugon.modules.device.consts.DevMaintenanceItemExecuteStatus;
import com.sugon.modules.device.consts.DevMaintenancePlanFreType;
import com.sugon.modules.device.consts.DevMaintenanceTicketStatus;
import com.sugon.modules.device.model.dto.WeekRangeItemDTO;
import com.sugon.modules.device.model.entity.DevMaintenancePlanEntity;
import com.sugon.modules.device.model.vo.*;
import com.sugon.modules.device.service.IDeviceMaintenanceManager;
import com.sugon.modules.utils.DateUtil;
import com.sugon.service.*;
import com.sugon.utils.MinioUtil;
import com.sugon.utils.ProcessInfoEnum;
import com.sugon.utils.R;
import com.sugon.utils.ShiroUtils;
import org.apache.shiro.util.Assert;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author ： YuXD
 * @description： 设备维护业务Manager实现类
 * @date ： 2020-08-10 下午 12:12
 * @version: 1.0
 */
@Service
public class DeviceMaintenanceManagerImpl implements IDeviceMaintenanceManager {
    @Autowired
    private DevMaintenancePlanService devPmPlanService;
    @Autowired
    private DeviceInfoService deviceInfoService;
    @Autowired
    private DevPlanRuleService devPlanRuleService;
    @Autowired
    private DevPmRuleItemService devPlanOptionService;
    @Resource
    private DevAmRulesOptionService devAmOptionService;
    @Autowired
    private DevMaintenancePlanItemService devPmPlanItemService;
    @Autowired
    private DevMaintenancePlanItemDao devPlanMainItemDao;
    @Autowired
    private DevMaintenPlanService devMaintenPlanService;
    @Resource
    private DevAmRulesService devMaintenanceRulesService;
    @Autowired
    private DevMaintenancePlanDao devMaintenancePlanDao;
    @Autowired
    private DevMaintenanceTicketService devMaintenanceTicketService;
    @Autowired
    private DevMaintenanceTicketItemService devPmTicketItemService;
    @Autowired
    private DevMaintenanceTicketItemDao devMaintenanceTicketItemDao;
    @Autowired
    private DevMainBaseService devMainBaseService;
    @Resource
    private DevMainBaseAmService devMainBaseAmService;
    @Autowired
    private SysMsgService sysMsgService;
    @Autowired
    private DevMaintenancePlanPreviewService devPmPlanPreviewService;
    @Autowired
    private DevMaintenancePlanPreviewDao devPmPlanPreviewDao;
    @Autowired
    private TicketLiveImageService ticketLiveImageService;
    @Resource
    private SysOssService sysOssService;
    @Resource
    private DevFaultPreventMeasureDao devFaultPreventMeasureDao;

    //@Override
    //public Map<String, Object> generateDevMaintenancePlanPreviewTemplateData(String yearly, String planIdlist) {
    //    if (StrUtil.isNotEmpty(yearly)) {
    //        // 清空指定年度设备维护计划预览项
    //        //devMaintenancePlanPreviewService.delete(yearly);
    //    }
    //    // 声明返回结果
    //    Map<String, Object> devMaintenancePlanPreviewTemplateData = new HashMap<>(2);
    //    // 声明周日期列表
    //    Date begionOfYear = DateUtil.initDate(NumberUtil.parseInt(yearly), 1, 1);
    //    List<WeekRangeItemDTO> weeksList = DateUtil.listWeeksOfYear(null, begionOfYear, begionOfYear, DateUtil.initDate(NumberUtil.parseInt(yearly), 12, 31));
    //    // 声明维护项列表
    //    List<Map<String, Object>> planItemList = new ArrayList<>();
    //    // 获取yearly年份下所有的设备维护计划
    //    Map<String, Object> param = new HashMap<>();
    //    param.put("yearly", yearly);
    //    if (StrUtil.isNotEmpty(planIdlist)) {
    //        param.put("planIdlist", planIdlist);
    //    }
    //    List<DevMaintenancePlanEntity> devMaintenancePlanList = devMaintenancePlanService.queryList(param);
    //    if (CollectionUtil.isNotEmpty(devMaintenancePlanList)) {
    //         /*
    //            1、获取所有计划维护项
    //            2、遍历维护项，根据每一项设置的日期和时间间隔，找到并设置
    //            没有的项不进行任何设置
    //         */
    //        List<String> planIdList = devMaintenancePlanList.stream().map(DevMaintenancePlanEntity::getId).collect(Collectors.toList());
    //        List<DevMaintenancePlanItemDetailVO> planItemDetailList = devMaintenancePlanDao.getByPlanIds(planIdList);
    //        if (CollectionUtil.isNotEmpty(planItemDetailList)) {
    //            for (DevMaintenancePlanItemDetailVO planItemDetail : planItemDetailList) {
    //                // 获取当初设定的执行日期
    //                Date date = DateUtil.initDate(NumberUtil.parseInt(yearly), planItemDetail.getMonthNum(), planItemDetail.getDayNum());
    //                Map<String, Object> planItemDetailMap = BeanUtil.beanToMap(planItemDetail);
    //                recursiveSetExePoint(date, null, planItemDetail.getFreRate(), planItemDetailMap, true, false);
    //                for (int i = 1; i <= 53; i++) {
    //                    planItemDetailMap.putIfAbsent("value" + i, "");
    //                }
    //                planItemList.add(planItemDetailMap);
    //            }
    //            // 统计工时
    //            for (WeekRangeItemDTO weekRangeItem : weeksList) {
    //                String key = weekRangeItem.getWeekOfYearNoT();
    //                for (Map<String, Object> planItemDetail : planItemList) {
    //                    if (StrUtil.isNotEmpty(MapUtil.getStr(planItemDetail, key))) {
    //                        weekRangeItem.addManHours((com.sugon.modules.utils.MapUtil.getInt(planItemDetail, "checkDatePrud", 0) + com.sugon.modules.utils.MapUtil.getInt(planItemDetail, "checkDateUprud", 0)) * com.sugon.modules.utils.MapUtil.getInt(planItemDetail, "perEv", 0));
    //                    }
    //                }
    //            }
    //        }
    //    }
    //    devMaintenancePlanPreviewTemplateData.put("planItemList", planItemList);
    //    devMaintenancePlanPreviewTemplateData.put("weeksList", weeksList);
    //    return devMaintenancePlanPreviewTemplateData;
    //}

    @Override
    public Map<String, Object> generateDevMaintenancePlanPreviewTemplateData(String yearly, String planIdlist) {
        if (StrUtil.isNotEmpty(yearly)) {
            // 清空指定年度设备维护计划预览项
            //devMaintenancePlanPreviewService.delete(yearly);
        }
        // 声明返回结果
        Map<String, Object> devMaintenancePlanPreviewTemplateData = new HashMap<>(2);
        // 声明周日期列表
        Date begionOfYear = DateUtil.initDate(NumberUtil.parseInt(yearly), 1, 1);
        List<WeekRangeItemDTO> weeksList = DateUtil.listWeeksOfYear(null, begionOfYear, begionOfYear, DateUtil.initDate(NumberUtil.parseInt(yearly), 12, 31));
        // 声明维护项列表
        final List<Map<String, Object>> planItemList = new ArrayList<>();
        // 获取yearly年份下所有的设备维护计划
        Map<String, Object> param = new HashMap<>();
        param.put("yearly", yearly);
        if (StrUtil.isNotEmpty(planIdlist)) {
            param.put("planIdlist", planIdlist);
        }
        List<DevMaintenancePlanEntity> devMaintenancePlanList = devPmPlanService.queryList(param);
        if (CollectionUtil.isNotEmpty(devMaintenancePlanList)) {
             /*
                1、获取所有计划维护项
                2、遍历维护项，根据每一项设置的日期和时间间隔，找到并设置
                没有的项不进行任何设置
             */
            List<String> planIdList = devMaintenancePlanList.stream().map(DevMaintenancePlanEntity::getId).collect(Collectors.toList());
            List<DevMaintenancePlanItemDetailVO> planItemDetailList = devPmPlanPreviewDao.getByPlanIds(planIdList);
            if (CollectionUtil.isNotEmpty(planItemDetailList)) {
                int[] code = {0x25CF};
                // 一个设备一个维护项为一行
                Map<String, List<DevMaintenancePlanItemDetailVO>> temMap = planItemDetailList.stream().collect(Collectors.groupingBy(item -> item.getDevId() + item.getMainBaseId()));
                temMap.forEach((uniqueCode, itemList) -> {
                    Map<String, Object> planItemDetailMap = BeanUtil.beanToMap(itemList.get(0));
                    List<Integer> weeklyList = itemList.stream().map(item -> item.getWeeksOfYear()).collect(Collectors.toList());
                    for (Integer weekOfYear : weeklyList) {
                        // 判断下是否实施过，如果实施过
                        planItemDetailMap.put("value" + weekOfYear, new String(code, 0, 1));
                    }
                    for (int i = 1; i <= 53; i++) {
                        String value = "";
                        if (weeklyList.contains(i)) {
                            value = new String(code, 0, 1);
                        }
                        planItemDetailMap.putIfAbsent("value" + i, value);
                    }
                    planItemList.add(planItemDetailMap);
                });

                // 统计工时
                Map<Integer, List<DevMaintenancePlanItemDetailVO>> groupedMap = planItemDetailList.stream().collect(Collectors.groupingBy(DevMaintenancePlanItemDetailVO::getWeeksOfYear));
                for (WeekRangeItemDTO weekRangeItem : weeksList) {
                    List<DevMaintenancePlanItemDetailVO> temItems = groupedMap.get(weekRangeItem.getWeeklyOfYear());
                    if (CollectionUtil.isEmpty(temItems)) {
                        continue;
                    }
                    weekRangeItem.addManHours(temItems.stream().mapToLong(item -> item.getCheckDatePrud() + item.getCheckDateUprud()).sum());
                }
            }
        }
        // 一个设备放到一起
        List<Map<String, Object>> planItemList2 = planItemList.stream().sorted(Comparator.comparing(o -> MapUtil.getStr(o, "devCode"))).collect(Collectors.toList());
        devMaintenancePlanPreviewTemplateData.put("planItemList", planItemList2);
        devMaintenancePlanPreviewTemplateData.put("weeksList", weeksList);
        return devMaintenancePlanPreviewTemplateData;
    }

    @Override
    public Map<String, Object> generatePlanImplementFollowTemplateData(String planId) {
        // 声明返回结果
        Map<String, Object> devMaintenancePlanPreviewTemplateData = new HashMap<>(2);
        // 声明维护项列表
        List<Map<String, Object>> planItemList = new ArrayList<>();

        DevMaintenancePlanEntity devMaintenancePlan = devPmPlanService.queryObject(planId);
        Assert.notNull(devMaintenancePlan, "设备维护计划不存在！");

        Integer yearly = devMaintenancePlan.getYearly();

        // 声明周日期列表
        Date begionOfYear = DateUtil.initDate(devMaintenancePlan.getYearly(), 1, 1);
        List<WeekRangeItemDTO> weeksList = DateUtil.listWeeksOfYear(null, begionOfYear, begionOfYear, DateUtil.initDate(yearly, 12, 31));
        List<DevMaintenancePlanItemDetailVO> planItemDetailList = devMaintenancePlanDao.getByPlanId(planId);
        if (CollectionUtil.isNotEmpty(planItemDetailList)) {
            for (DevMaintenancePlanItemDetailVO planItemDetail : planItemDetailList) {
                // 获取当初设定的执行日期
                Date date = DateUtil.initDate(yearly, planItemDetail.getMonthNum(), planItemDetail.getDayNum());
                Map<String, Object> planItemDetailMap = BeanUtil.beanToMap(planItemDetail);
                // 设置预计维护实施时间段标点
                recursiveSetExePoint(date, null, planItemDetail.getFreRate(), planItemDetailMap, true, false);

                // 获取当前维护项已完成的周次
                Set<Integer> implementWeeksOfYearList = new HashSet<>();
                List<DevMaintenancePlanItemImplementDetailDTO> implementDetailList = planItemDetail.getImplementDetailList();
                if (CollectionUtil.isNotEmpty(implementDetailList)) {
                    for (DevMaintenancePlanItemImplementDetailDTO implementDetail : implementDetailList) {
                        if (implementDetail.getStatus() == 1 && implementDetail.getImplementDate() != null) {
                            implementWeeksOfYearList.add(cn.hutool.core.date.DateUtil.weekOfYear(implementDetail.getImplementDate()));
                        }
                    }
                }
                for (int i = 1; i <= 53; i++) {
                    String key = "value" + i;
                    if (implementWeeksOfYearList.contains(i)) {
                        int[] code = {0x221A};
                        String implementStatus = new String(code, 0, 1);
                        Object value = planItemDetailMap.putIfAbsent(key, implementStatus);
                        if (value != null) {
                            planItemDetailMap.put(key, value + " " + implementStatus);
                        }
                    } else {
                        planItemDetailMap.putIfAbsent("value" + i, "");
                    }
                }
                planItemList.add(planItemDetailMap);
            }
        }
        devMaintenancePlanPreviewTemplateData.put("planItemList", planItemList);
        devMaintenancePlanPreviewTemplateData.put("weeksList", weeksList);
        return devMaintenancePlanPreviewTemplateData;
    }

    /**
     * 递归循环设置计划实施点
     *
     * @param date              当前日期
     * @param freRate           递归频率
     * @param planItemDetailMap 维护计划内容
     * @param isFirst           是否是第一次
     * @param isRecord          是否记录DEV_MAINTENANCE_PLAN_PREVIEW
     */
    private void recursiveSetExePoint(Date date, Date lastDayCurrentYear, Integer freRate, Map<String, Object> planItemDetailMap, boolean isFirst, boolean isRecord) {
        if (!isFirst) {
            // 根据设备维护计划实施频率对date进行偏移
            switch (freRate) {
                case DevMaintenancePlanFreType.WEEKLY:
                    // 每周执行一次
                    date = cn.hutool.core.date.DateUtil.offsetWeek(date, 1);
                    break;
                case DevMaintenancePlanFreType.FORTNIGHT:
                    // 每半个月执行一次
                    date = cn.hutool.core.date.DateUtil.offsetWeek(date, 2);
                    break;
                case DevMaintenancePlanFreType.MONTH:
                    // 每月执行一次
                    date = cn.hutool.core.date.DateUtil.offsetMonth(date, 1);
                    break;
                case DevMaintenancePlanFreType.QUARTER:
                    // 每季度执行一次
                    date = cn.hutool.core.date.DateUtil.offsetMonth(date, 3);
                    break;
                case DevMaintenancePlanFreType.HALF_YEAR:
                    // 每半年执行一次
                    date = cn.hutool.core.date.DateUtil.offsetMonth(date, 6);
                    break;
                case DevMaintenancePlanFreType.YEAR:
                    // 每年执行一次
                    date = cn.hutool.core.date.DateUtil.offsetMonth(date, 12);
                    break;
            }
        } else {
            lastDayCurrentYear = cn.hutool.core.date.DateUtil.endOfYear(date);
        }
        // 如果计划不再实施起止时间段内，那么不做任何处理
        if (date.compareTo(MapUtil.getDate(planItemDetailMap, "endDate")) > 0 || date.compareTo(lastDayCurrentYear) > 0) {
            return;
        }
        if (DateUtil.between(date, MapUtil.getDate(planItemDetailMap, "startDate"), MapUtil.getDate(planItemDetailMap, "endDate"))) {
            int weekOfYear = cn.hutool.core.date.DateUtil.weekOfYear(date);
            // 如果不是第一次且weekOfYear为1,那么计算当前日期的前一周的周次+1，修复无法显示最后一周BUG
            if (!isFirst && weekOfYear == 1) {
                weekOfYear = cn.hutool.core.date.DateUtil.weekOfYear(cn.hutool.core.date.DateUtil.offsetWeek(date, -1)) + 1;

            }
            int[] code = {0x25CF};
            // 判断下是否实施过，如果实施过
            planItemDetailMap.put("value" + weekOfYear, new String(code, 0, 1));
            if (isRecord) {
                // 生成设备预览记录，便于生成工单
                devPmPlanPreviewService.recordDeviceMaintenancePlanExeItem(MapUtil.getStr(planItemDetailMap, "planId"), MapUtil.getStr(planItemDetailMap, "id"), MapUtil.getStr(planItemDetailMap, "devId"), MapUtil.getStr(planItemDetailMap, "mainBaseId"), cn.hutool.core.date.DateUtil.year(date), weekOfYear);
            }
        }
        recursiveSetExePoint(date, lastDayCurrentYear, freRate, planItemDetailMap, false, isRecord);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean addDeviceMaintenanceRule(DevMaintenanceRuleParamVO devMaintenanceRuleParam) {
        // 设置基础信息
        DevMaintenPlanEntity devMaintenPlan = new DevMaintenPlanEntity();
        CopyOptions copyOptions = CopyOptions.create().setIgnoreNullValue(true).setIgnoreError(true);
        BeanUtil.copyProperties(devMaintenanceRuleParam, devMaintenPlan, copyOptions);
        // 设置设备相关
        DeviceInfoEntity deviceInfo = deviceInfoService.queryObject(devMaintenPlan.getDevId());
        Assert.notNull(deviceInfo, "非法设备[" + devMaintenPlan.getDeviceName() + "]");
        devMaintenPlan.setDevId(deviceInfo.getId());
        devMaintenPlan.setProgress(ProcessProgressConst.NEW);
        devMaintenPlan.setIsValid(1);
        if (StrUtil.isEmpty(devMaintenPlan.getRuleName())) {
            devMaintenPlan.setRuleName(deviceInfo.getDevName() + "_" + "维护规程");
        }
        if (StrUtil.isEmpty(devMaintenPlan.getPlanCon())) {
            devMaintenPlan.setPlanCon("无");
        }
        int rows = devMaintenPlanService.save(devMaintenPlan);
        if (rows > 0) {
            // 1、根据供应厂商编码、设备类别和规程类型查询可关联的设备维护项列表，并建立关系
            String devMaintenanceRuleId = devMaintenPlan.getId();
            List<DevMainBaseEntity> devMainBaseList = devMainBaseService.getBySupplyAndType(deviceInfo.getDevSupply(), deviceInfo.getDevTypeS(), NumberUtil.parseInt(devMaintenPlan.getReserve1()));
            if (CollectionUtil.isNotEmpty(devMainBaseList)) {
                for (DevMainBaseEntity devMainBase : devMainBaseList) {
                    //维护规程与维护库关联
                    DevPlanOptionEntity devPlanOption = new DevPlanOptionEntity(devMaintenanceRuleId, devMainBase.getId());
                    devPlanOptionService.save(devPlanOption);
                }
            }
            // 2、修改进度为部门审核中
            devMaintenPlan.setProgress(ProcessProgressConst.DEPT_APPROVING);
            devMaintenPlanService.update(devMaintenPlan);
            // 3、保存系统审批消息
            SysMsgEntity sysMsg = new SysMsgEntity();
            sysMsg.setDataId(devMaintenanceRuleId);
            sysMsg.setDataUrl("../device/devmaintenplan.html?Id=" + devMaintenanceRuleId);
            sysMsgService.addApproveItem(ProcessInfoEnum.DEV_WHGC, sysMsg, 0);
        }
        return rows > 0;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean createDeviceAmMaintenanceRules(SaveDevAmRuleParam rulesParam) {
        // 设置基础信息
        DevAmRulesEntity amMaintenanceRules = new DevAmRulesEntity();
        CopyOptions copyOptions = CopyOptions.create().setIgnoreNullValue(true).setIgnoreError(true);
        BeanUtil.copyProperties(rulesParam, amMaintenanceRules, copyOptions);
        amMaintenanceRules.setProgress(ProcessProgressConst.NEW);
        amMaintenanceRules.setIsValid(1);
        if (StrUtil.isEmpty(amMaintenanceRules.getRuleName())) {
            amMaintenanceRules.setRuleName(rulesParam.getDevName() + "_" + "维护规程");
        }
        if (StrUtil.isEmpty(amMaintenanceRules.getPlanCon())) {
            amMaintenanceRules.setPlanCon("无");
        }
        int rows = devMaintenanceRulesService.save(amMaintenanceRules);
        if (rows > 0) {
            // 1、根据供应厂商编码、设备类别和规程类型查询可关联的设备维护项列表，并建立关系
            String devMaintenanceRuleId = amMaintenanceRules.getId();
            List<DevMainBaseAmEntity> devMainBaseList = devMainBaseAmService.getBySupplyAndType(rulesParam.getDevSupply(), rulesParam.getDevTypeS());
            if (CollectionUtil.isNotEmpty(devMainBaseList)) {
                for (DevMainBaseAmEntity amItem : devMainBaseList) {
                    //维护规程与维护库关联
                    DevAmRulesOptionEntity amRulesItem = new DevAmRulesOptionEntity(devMaintenanceRuleId, amItem.getId());
                    devAmOptionService.save(amRulesItem);
                }
            }
            // 2、修改进度为部门审核中
            amMaintenanceRules.setProgress(ProcessProgressConst.DEPT_APPROVING);
            devMaintenanceRulesService.update(amMaintenanceRules);
            // 3、保存系统审批消息
            SysMsgEntity sysMsg = new SysMsgEntity();
            sysMsg.setDataId(devMaintenanceRuleId);
            sysMsg.setDataUrl("../device/devMaintenanceRules.html?Id=" + devMaintenanceRuleId);
            sysMsgService.addApproveItem(ProcessInfoEnum.DEV_WHGC, sysMsg, 0);
        }
        return rows > 0;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean correlateMaintenancePlanAndRule(String planId, String[] ruleIds) {
        /*
        1、建立设备维护计划与设备维护规程之间的关联关系
        2、建立设备维护计划与设备维护库中的维护项之间的关联关系
         */
        for (String ruleId : ruleIds) {
            DevMaintenPlanEntity devMaintenPlan = devMaintenPlanService.queryObject(ruleId);
            if (devMaintenPlan == null) {
                continue;
            }
            // 1、建立维护计划和维护规程之间的关联关系
            if (!devPlanRuleService.checkIsExists(planId, ruleId)) {
                devPlanRuleService.save(new DevPlanRuleEntity(planId, ruleId));
            }
            // 2、建立维护计划和维护计划项之间的关联关系
            // 获取规程下的维护明细列表
            List<DevPlanOptionEntity> devPlanOptionList = devPlanOptionService.getByPlanId(ruleId);
            if (CollectionUtil.isEmpty(devPlanOptionList)) {
                continue;
            }
            DevMaintenancePlanItemEntity devPlanMainItem;
            for (DevPlanOptionEntity devPlanOptionEntity : devPlanOptionList) {
                String mainBaseId = devPlanOptionEntity.getMainBaseId();
                String devId = devMaintenPlan.getDevId();
                if (!devPmPlanItemService.isExists(planId, devId, mainBaseId)) {
                    devPlanMainItem = new DevMaintenancePlanItemEntity(planId, mainBaseId);
                    devPlanMainItem.setDevId(devId);
                    devPmPlanItemService.save(devPlanMainItem);
                }
            }
        }
        return true;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean adjustDevMaintenancePlanItem(List<DevMaintenancePlanItemDateAdjustParamVO> devMaintenancePlanItemParams) {
        if (CollectionUtil.isEmpty(devMaintenancePlanItemParams)) {
            return true;
        }
        List<DevMaintenancePlanItemEntity> planItemList = CollectionUtil.newArrayList();
        Set<String> pmPlanIdSet = CollectionUtil.newHashSet();
        for (DevMaintenancePlanItemDateAdjustParamVO devMaintenancePlanItemParam : devMaintenancePlanItemParams) {
            String[] devMaintenancePlanItemIdArray = devMaintenancePlanItemParam.getDevMaintenancePlanItemIds().split(",");
            if (ArrayUtil.isEmpty(devMaintenancePlanItemIdArray)) {
                continue;
            }
            for (String planItemId : devMaintenancePlanItemIdArray) {
                DevMaintenancePlanItemEntity planItem = devPlanMainItemDao.queryObject(planItemId);
                cn.hutool.core.lang.Assert.notNull(planItem);
                pmPlanIdSet.add(planItem.getPlanId());
                // 周计划调整时不包含月份字符串
                if (devMaintenancePlanItemParam.getMonthNum() != null) {
                    planItem.setMonthNum(devMaintenancePlanItemParam.getMonthNum());
                }
                planItem.setDayNum(devMaintenancePlanItemParam.getDayNum());
                int updateFlag = devPmPlanItemService.update(planItem);
                cn.hutool.core.lang.Assert.isTrue(updateFlag > 0, "更新设备维护项失败！");
                planItemList.add(planItem);
            }
        }
        // 重新生成调整想的预览数据
        if (CollectionUtil.isNotEmpty(planItemList)) {
            devPmPlanPreviewService.rebuild(planItemList);
        }
        // 移除每个维护计划中排除的周次
        for (String pmPlanId : pmPlanIdSet) {
            DevMaintenancePlanEntity pmPlan = devPmPlanService.queryObject(pmPlanId);
            cn.hutool.core.lang.Assert.isTrue(pmPlan != null);
            // 获取需要排除的周次Set
            Set<Integer> excludeWeeklySet = pmPlan.loadExcludeWeeklySet();
            if (CollectionUtil.isEmpty(excludeWeeklySet)) {
                continue;
            }
            // 删除非工作周的预览数据
            devPmPlanPreviewDao.conditionDelete(pmPlanId, pmPlan.getYearly(), excludeWeeklySet);
        }
        return true;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean completeDevMaintenanceOption(DevMaintenanceTicketItemEntity devPmTicketItem) {
        /*
            完成需要区分正常完成和延期完成两种情形
            逻辑：如果在规定时间内完成，那么属于正常完成，否则属于延期完成
         */
        Date executeDate = cn.hutool.core.date.DateUtil.date();
        DevMaintenanceTicketEntity maintenanceTicket = devMaintenanceTicketService.queryObject(devPmTicketItem.getDevMainTicketId());
        cn.hutool.core.lang.Assert.notNull(maintenanceTicket);
        Integer executeStatus;
        if (DateUtil.between(executeDate, maintenanceTicket.getStartTime(), maintenanceTicket.getFinalEndTime())) {
            executeStatus = DevMaintenanceItemExecuteStatus.ED;
        } else {
            executeStatus = DevMaintenanceItemExecuteStatus.DELAY_ED;
        }
        devPmTicketItem.setImplementDate(executeDate);
        devPmTicketItem.setStatus(executeStatus);
        // 更新设备维护工单项状态
        if (devPmTicketItemService.update(devPmTicketItem) > 0) {
            // 保存工单现场照片
            List<String> liveImageList = devPmTicketItem.getLiveImageList();
            if (CollectionUtil.isNotEmpty(liveImageList)) {
                ticketLiveImageService.batchUpdateTicketImages(devPmTicketItem.getId(), "MAINTENANCE", "维护现场", liveImageList);
            }
            // 调整工单状态
            adjustTicketStatus(devPmTicketItem.getDevMainTicketId());
        }
        return true;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean modifyLiveImage(DevMaintenanceTicketItemEntity pmTicketItem, MultipartFile[] liveImageArray) {
        /*
            1、更新维护项信息
            2、删除已有的
            3、保存最新工单信息
         */
        pmTicketItem.setImplementerId(ShiroUtils.getUserId());
        pmTicketItem.setImplementDate(cn.hutool.core.date.DateUtil.date());
        // 更新设备维护工单项状态
        if (devPmTicketItemService.update(pmTicketItem) > 0) {
            // 删除已有的工单执行现场照片
            List<TicketLiveImageEntity> existsLiveImages = ticketLiveImageService.queryList(pmTicketItem.getId(), "MAINTENANCE");
            if (CollectionUtil.isNotEmpty(existsLiveImages)) {
                for (TicketLiveImageEntity existsLiveImage : existsLiveImages) {
                    // 删除原工单现场照片
                    MinioUtil.removeObject("erms", existsLiveImage.getPath());
                    // 删除原工单现场照片记录
                    ticketLiveImageService.delete(existsLiveImage.getId());
                }
            }
            // 保存最新工单现场照片
            for (MultipartFile liveImage : liveImageArray) {
                R uploadResult = sysOssService.upload("device", "pm", liveImage);
                if (uploadResult != null && uploadResult.containsKey("url")) {
                    ticketLiveImageService.addTicketLiveImage(pmTicketItem.getId(), "MAINTENANCE", (String) uploadResult.get("url"));
                }
            }
        }
        return true;
    }

    /**
     * 调整工单状态
     *
     * @param devMaintenanceTicketId 设备维护工单ID
     * @return
     */
    private void adjustTicketStatus(String devMaintenanceTicketId) {
        /*
            获取当前维护工单的状态
            如果是非维护中的状态：那么需要更新工单状态、接收时间和执行时间字段
            如果是维护中状态：校验是否所有的工单项都结束？如果是那么更新工单状态为已完成
         */
        DevMaintenanceTicketEntity devMaintenanceTicket = devMaintenanceTicketService.queryObject(devMaintenanceTicketId);
        if (DevMaintenanceTicketStatus.WAIT_EXECUTE.equals(devMaintenanceTicket.getStatus())) {
            // 校验工单是否刚刚开始，如果是，则修改接单时间和开始时间
            int completedNum = devMaintenanceTicketItemDao.countTicketOptionNum(devMaintenanceTicketId, DevMaintenanceItemExecuteStatus.DELAY_ED, DevMaintenanceItemExecuteStatus.ED);
            if (completedNum > 0) {
                devMaintenanceTicket.setStatus(DevMaintenanceTicketStatus.MAINTAINING);
                devMaintenanceTicketService.update(devMaintenanceTicket);
                // 调整预防措施进度
                devFaultPreventMeasureDao.updateProgress(devMaintenanceTicketId, DevFaultPreventProgress.ING, "DEV_MAINTENANCE_TICKET");
            }
        }
        // 校验工单的所有维护项是否已完成，如果已完成，那么修改工单状态为已完成
        int uncompletedNum = devMaintenanceTicketItemDao.countTicketOptionNum(devMaintenanceTicketId, DevMaintenanceItemExecuteStatus.UN);
        if (uncompletedNum == 0) {
            Integer status;
            if (DateUtil.between(cn.hutool.core.date.DateUtil.date(), devMaintenanceTicket.getStartTime(), devMaintenanceTicket.getFinalEndTime())) {
                status = DevMaintenanceTicketStatus.COMPLETE;
            } else {
                status = DevMaintenanceTicketStatus.DELAY_COMPLETE;
            }
            devMaintenanceTicket.setStatus(status);
            devMaintenanceTicketService.update(devMaintenanceTicket);
            // 调整预防措施进度
            devFaultPreventMeasureDao.updateProgress(devMaintenanceTicketId, DevFaultPreventProgress.ED, "DEV_MAINTENANCE_TICKET");
        }
    }

}
